
//
// 130423 - AH - Created.
//

package org.japril.jutil.xmloperations;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

/**
 * <p>
 *   Base class for 
 *   {@link XmlOperation}.
 * </p>
 * @author Arne Halvorsen (AH)
 */
public abstract class AbstractXmlOperation implements XmlOperation
{
  private final String m_name;
  
  private String m_desc=null;
  
  private final List<String> m_paths=new ArrayList<String>();

  private final static XPath m_path=XPathFactory.newInstance().newXPath();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param name {@link #getName()}.
   */
  protected AbstractXmlOperation(String name)
  {
    if (name==null)
    {
      throw new NullPointerException("name");
    }
    
    name=name.trim();
    if (name.length()==0)
    {
      throw new IllegalArgumentException("name is the empty string");
    }
    
    m_name=name;
  }
  
  /**
   * <p>
   *   Sets description.
   * </p>
   * @param desc Description. The empty string or {@code null} clears.
   */
  public void setDesc(String desc)
  {
    m_desc=(desc==null) ? "" : desc.trim();
    m_desc=(m_desc.length()==0) ? null : m_desc;
  }
  
  /**
   * <p>
   *   Gets description.
   * </p>
   * @return Description. 
   */
  public String getDesc(){ return m_desc; }
  
  /**
   * <p>
   *   Adds path.
   * </p>
   * @param path Path.
   * @throws IllegalArgumentException If {@code path} not valid XPath.
   */
  public final void addPath(String path)
  {
    if (path==null)
    { 
      throw new NullPointerException("path");
    }
    
    try
    {
      m_path.compile(path);
      m_paths.add(path);
    }
    catch (XPathExpressionException xpex)
    {
      IllegalArgumentException iax=new IllegalArgumentException();
      iax.initCause(xpex);
      throw iax;
    }
  }
  
  /**
   * <p>
   *   Removes path.
   * </p>
   * @param idx Index to path to remove.
   * @throws IndexOutOfBoundsException If {@code idx<0 || idx>=getPathCount()}.
   */
  public final void removePath(int idx){ m_paths.remove(idx); }
  
  // Specified in XmlOperation.
  public String getName(){ return m_name; }

  // Specified in XmlOperation.
  public int getPathCount(){ return m_paths.size(); }

  // Specified in XmlOperation.
  public String getPath(int idx){ return m_paths.get(idx); }
  
}
